package com.touch.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Set;

import com.touch.account.Account;
import com.touch.core.NetConstants;
import com.touch.core.avatar.Avatar;
import com.touch.core.net.NetListener;
import com.touch.core.script.ByteEncoder;
import com.touch.core.util.IOTools;

public class ServerSocketEvents implements NetListener
{

	public void messageReceived(Object oHost, byte[] message) 
	{	
		final InetSocketAddress host = (InetSocketAddress)oHost;
		if(NetConstants.compare(NetConstants.REQUEST_CONNECTION, message))
			processConnectionRequest(host);
		else if(NetConstants.compare(NetConstants.REQUEST_NEW_ACCOUNT, message))
			processNewAccount(host, message);
		else if(NetConstants.compare(NetConstants.REQUEST_LOGIN, message))
			processLogin(host, message);
		else if(NetConstants.compare(NetConstants.RANDOMIZE_STATS, message))
			processRandomStats(host, message);
		else if(NetConstants.compare(NetConstants.REQUEST_CLASS_INFO, message))
			processClassRequest(host);
		else
			System.out.println("unrecognized message: " + new String(message));
	}		
	private void processLogin(InetSocketAddress host, byte[] message)
	{
		message = ByteEncoder.getSubByteArray(message, 4, message.length - 1);
		String sMessage[] = new String(message).split(new String(NetConstants.SEP_SEQ));
		if(sMessage.length != 2)
			return;
		String name = sMessage[0];
		String password = sMessage[1];
		
		Account lAcc = Account.loadAccount(name);
		if(lAcc.banned)
		{
			ServerControls.SERVER_SOCKET.sendTo(host, NetConstants.ACCOUNT_BANNED);
			return;
		}
		if(!password.equals(lAcc.password))
		{
			ServerControls.SERVER_SOCKET.sendTo(host, NetConstants.FAILED_LOGIN);
			return;
		}
		
		ServerControls.AccountMap.put(name, lAcc);
		ServerControls.SERVER_SOCKET.associate(lAcc, host);
		for(int i = 0; i < 3; i++)
			ServerControls.SERVER_SOCKET.sendTo(host, LOGIN_PACKET(name, i));
	}
	private void processConnectionRequest(InetSocketAddress host)
	{
		ServerControls.SERVER_SOCKET.sendTo(host, NetConstants.REQUEST_CONNECTION);
	}
	private void processNewAccount(InetSocketAddress host, byte[] message)
	{
		message = ByteEncoder.getSubByteArray(message, 4, message.length - 1);
		String sMessage[] = new String(message).split(new String(NetConstants.SEP_SEQ));
		if(sMessage.length != 3)
			return;
		String name = sMessage[0];
		String password = sMessage[1];
		System.out.println("new acc");
		if(Account.isValidNewAccount(name))
		{
			try
			{																
				ServerControls.AccountMap.put(name, Account.makeAccount(name, password));
				ServerControls.SERVER_SOCKET.sendTo(host, NetConstants.REQUEST_NEW_ACCOUNT);				
			}
			catch (IOException e) 
			{							
				ServerControls.SERVER_SOCKET.sendTo(host, NetConstants.FAILED_MAKE_NEW_ACCOUNT);
			}
		}		
		else
			ServerControls.SERVER_SOCKET.sendTo(host, NetConstants.FAILED_MAKE_NEW_ACCOUNT);
	}
	private void processRandomStats(InetSocketAddress host, byte[] message)
	{
		//String cls = new String(ByteEncoder.getSubByteArray(message, 4, message.length - 1));
		//TODO: read min/max for the specified class.
		byte[] stat1 = ByteEncoder.intToByteArray(ServerControls.randomInt(4, 10));
		byte[] stat2 = ByteEncoder.intToByteArray(ServerControls.randomInt(4, 10));
		byte[] stat3 = ByteEncoder.intToByteArray(ServerControls.randomInt(4, 10));
		byte[] stat4 = ByteEncoder.intToByteArray(ServerControls.randomInt(4, 10));
		byte[] hp = ByteEncoder.intToByteArray(50);
		byte[] mp = ByteEncoder.intToByteArray(50);
		byte[] sp = ByteEncoder.intToByteArray(50);
		
		message = NetConstants.RANDOMIZE_STATS;
		message = ByteEncoder.appendToByteArray(message, stat1, stat2, stat3, stat4, hp, mp, sp);
		ServerControls.SERVER_SOCKET.sendTo(host, message);
	}
	private void processClassRequest(InetSocketAddress host)
	{
		Set<String> classNames = ServerControls.JobMap.keySet();
		byte[] message = NetConstants.REQUEST_CLASS_INFO;
		for(String className: classNames)
		{
			if(className != null)
				message = ByteEncoder.appendToByteArray(message, ByteEncoder.stringToByteArray(className), NetConstants.SEP_SEQ);
		}
		
		ServerControls.SERVER_SOCKET.sendTo(host, message);
	}
	private byte[] LOGIN_PACKET(String accName, int charnum)
	{
		byte[] message = NetConstants.REQUEST_LOGIN.clone();
		return ByteEncoder.appendToByteArray(message, 
				ByteEncoder.intToByteArray(charnum),
				IOTools.readFileAsBytes(Avatar.getDataPath(accName, charnum)));		
	}
}
